package godbv2

import (
	"errors"
	"fmt"
	"github.com/spf13/cast"
	"github.com/xwb1989/sqlparser"
	"regexp"
)

var reg = regexp.MustCompile(":v\\d")

type SelectSQL struct {
	Columns    string
	Table      string
	Where      string
	GroupBy    string
	Having     string
	OrderBy    string
	LimitStart int64
	LimitLen   int64
}

// SelectSQLParser 解析select语句
func SelectSQLParser(sql string) (SelectSQL, error) {
	ret := SelectSQL{}
	stmt, err := sqlparser.Parse(sql)
	if err != nil {
		return ret, fmt.Errorf("sql语句解析错误:%w", err)
	}
	switch stmt := stmt.(type) {
	case *sqlparser.Select:
		buf := sqlparser.NewTrackedBuffer(nil)
		stmt.SelectExprs.Format(buf)
		ret.Columns = buf.String()
		buf.Reset()
		stmt.From.Format(buf)
		ret.Table = buf.String()
		buf.Reset()
		where := stmt.Where
		if where != nil {
			stmt.Where.Format(buf)
			ret.Where = buf.String()
			if ret.Where != "" {
				ret.Where = regexp.MustCompile("(\\:v\\d+)").ReplaceAllString(ret.Where, "?")
			}
			buf.Reset()
		}
		stmt.GroupBy.Format(buf)
		ret.GroupBy = buf.String()
		buf.Reset()
		having := stmt.Having
		if having != nil {
			stmt.Having.Format(buf)
			ret.Having = buf.String()
			buf.Reset()
		}
		stmt.OrderBy.Format(buf)
		ret.OrderBy = buf.String()
		buf.Reset()
		limit := stmt.Limit
		if limit != nil {
			limit.Offset.Format(buf)
			ret.LimitStart = cast.ToInt64(buf.String())
			buf.Reset()
			limit.Rowcount.Format(buf)
			ret.LimitLen = cast.ToInt64(buf.String())
		}
		ret.Table = reg.ReplaceAllString(ret.Table, "?")
		ret.Where = reg.ReplaceAllString(ret.Where, "?")
		ret.Having = reg.ReplaceAllString(ret.Having, "?")
		return ret, nil
	default:
		return ret, errors.New("只支持select语句")
	}
}
